home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / mklev.c < prev    next >
C/C++ Source or Header  |  1993-01-14  |  34KB  |  1,381 lines

  1. /*    SCCS Id: @(#)mklev.c    3.1    92/10/10    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. /* #define DEBUG     /* uncomment to enable code debugging */
  7.  
  8. #ifdef DEBUG
  9. # ifdef WIZARD
  10. #define debugpline    if (wizard) pline
  11. # else
  12. #define debugpline    pline
  13. # endif
  14. #endif
  15.  
  16. /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
  17. /* croom->lx etc are schar (width <= int), so % arith ensures that */
  18. /* conversion of result to int is reasonable */
  19.  
  20.  
  21. static void FDECL(mkfount,(int,struct mkroom *));
  22. #ifdef SINKS
  23. static void FDECL(mksink,(struct mkroom *));
  24. #endif
  25. static void FDECL(mkaltar,(struct mkroom *));
  26. static void NDECL(makevtele);
  27. static void NDECL(clear_level_structures);
  28. static void NDECL(makelevel);
  29. static boolean FDECL(bydoor,(XCHAR_P,XCHAR_P));
  30. static struct mkroom *FDECL(find_branch_room, (coord *));
  31. static struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P));
  32. static boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*));
  33. static void FDECL(makeniche,(int));
  34. static void NDECL(make_niches);
  35. STATIC_PTR int FDECL(do_comp,(const genericptr,const genericptr));
  36. static void FDECL(dosdoor,(XCHAR_P,XCHAR_P,struct mkroom *,int));
  37. static void FDECL(join,(int,int,BOOLEAN_P));
  38. static void FDECL(do_room_or_subroom, (struct mkroom *,int,int,int,int,
  39.                        BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P));
  40. static void NDECL(makerooms);
  41. static void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
  42. static void FDECL(mkinvpos, (XCHAR_P,XCHAR_P,int));
  43. #ifdef MULDGN
  44. static void FDECL(mk_knox_portal, (XCHAR_P,XCHAR_P));
  45. #endif
  46.  
  47. #define create_vault()    create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE)
  48. #define init_vault()    vault_x = -1
  49. #define do_vault()    (vault_x != -1)
  50. static xchar        vault_x, vault_y;
  51. boolean goldseen;
  52. static boolean made_branch;    /* used only during level creation */
  53.  
  54. /* Args must be (const genericptr) so that qsort will always be happy. */
  55.  
  56. STATIC_PTR int
  57. do_comp(vx,vy)
  58. const genericptr vx;
  59. const genericptr vy;
  60. {
  61. #ifdef LINT
  62. /* lint complains about possible pointer alignment problems, but we know
  63.    that vx and vy are always properly aligned. Hence, the following
  64.    bogus definition:
  65. */
  66.     return (vx == vy) ? 0 : -1;
  67. #else
  68.     register const struct mkroom *x, *y;
  69.  
  70.     x = (const struct mkroom *)vx;
  71.     y = (const struct mkroom *)vy;
  72.     if(x->lx < y->lx) return(-1);
  73.     return(x->lx > y->lx);
  74. #endif /* LINT */
  75. }
  76.  
  77. static void
  78. finddpos(cc, xl,yl,xh,yh)
  79. coord    *cc;
  80. xchar    xl,yl,xh,yh;
  81. {
  82.     register xchar x, y;
  83.  
  84.     x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
  85.     y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
  86.     if(okdoor(x, y))
  87.         goto gotit;
  88.  
  89.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  90.         if(okdoor(x, y))
  91.             goto gotit;
  92.  
  93.     for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  94.         if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
  95.             goto gotit;
  96.     /* cannot find something reasonable -- strange */
  97.     x = xl;
  98.     y = yh;
  99. gotit:
  100.     cc->x = x;
  101.     cc->y = y;
  102.     return;
  103. }
  104.  
  105. void
  106. sort_rooms()
  107. {
  108. #if defined(SYSV) || defined(DGUX)
  109.     qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), do_comp);
  110. #else
  111.     qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp);
  112. #endif
  113. }
  114.  
  115. static void
  116. do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
  117.     register struct mkroom *croom;
  118.     int lowx, lowy;
  119.     register int hix, hiy;
  120.     boolean lit;
  121.     schar rtype;
  122.     boolean special;
  123.     boolean is_room;
  124. {
  125.     register int x, y;
  126.     struct rm *lev;
  127.  
  128.     /* locations might bump level edges in wall-less rooms */
  129.     /* add/subtract 1 to allow for edge locations */
  130.     if(!lowx) lowx++;
  131.     if(!lowy) lowy++;
  132.     if(hix >= COLNO-1) hix = COLNO-2;
  133.     if(hiy >= ROWNO-1) hiy = ROWNO-2;
  134.  
  135.     if(lit) {
  136.         for(x = lowx-1; x <= hix+1; x++) {
  137.             lev = &levl[x][max(lowy-1,0)];
  138.             for(y = lowy-1; y <= hiy+1; y++)
  139.                 lev++->lit = 1;
  140.         }
  141.         croom->rlit = 1;
  142.     } else
  143.         croom->rlit = 0;
  144.  
  145.     croom->lx = lowx;
  146.     croom->hx = hix;
  147.     croom->ly = lowy;
  148.     croom->hy = hiy;
  149.     croom->rtype = rtype;
  150.     croom->doorct = 0;
  151.     /* if we're not making a vault, doorindex will still be 0
  152.      * if we are, we'll have problems adding niches to the previous room
  153.      * unless fdoor is at least doorindex
  154.      */
  155.     croom->fdoor = doorindex;
  156.     croom->irregular = FALSE;
  157.  
  158.     croom->nsubrooms = 0;
  159.     croom->sbrooms[0] = (struct mkroom *) 0;
  160.     if (!special) {
  161.         for(x = lowx-1; x <= hix+1; x++)
  162.         for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  163.             levl[x][y].typ = HWALL;
  164.             levl[x][y].horizontal = 1;    /* For open/secret doors. */
  165.         }
  166.         for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  167.         for(y = lowy; y <= hiy; y++) {
  168.             levl[x][y].typ = VWALL;
  169.             levl[x][y].horizontal = 0;    /* For open/secret doors. */
  170.         }
  171.         for(x = lowx; x <= hix; x++) {
  172.         lev = &levl[x][lowy];
  173.         for(y = lowy; y <= hiy; y++)
  174.             lev++->typ = ROOM;
  175.         }
  176.         if (is_room) {
  177.         levl[lowx-1][lowy-1].typ = TLCORNER;
  178.         levl[hix+1][lowy-1].typ = TRCORNER;
  179.         levl[lowx-1][hiy+1].typ = BLCORNER;
  180.         levl[hix+1][hiy+1].typ = BRCORNER;
  181.         } else {    /* a subroom */
  182.         wallification(lowx-1, lowy-1, hix+1, hiy+1);
  183.         }
  184.     }
  185. }
  186.  
  187.  
  188. void
  189. add_room(lowx, lowy, hix, hiy, lit, rtype, special)
  190. register int lowx, lowy, hix, hiy;
  191. boolean lit;
  192. schar rtype;
  193. boolean special;
  194. {
  195.     register struct mkroom *croom;
  196.  
  197.     croom = &rooms[nroom];
  198.     do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
  199.                         rtype, special, (boolean) TRUE);
  200.     croom++;
  201.     croom->hx = -1;
  202.     nroom++;
  203. }
  204.  
  205. void
  206. add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
  207. struct mkroom *proom;
  208. register int lowx, lowy, hix, hiy;
  209. boolean lit;
  210. schar rtype;
  211. boolean special;
  212. {
  213.     register struct mkroom *croom;
  214.  
  215.     croom = &subrooms[nsubroom];
  216.     do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
  217.                         rtype, special, (boolean) FALSE);
  218.     proom->sbrooms[proom->nsubrooms++] = croom;
  219.     croom++;
  220.     croom->hx = -1;
  221.     nsubroom++;
  222. }
  223.  
  224. static void
  225. makerooms()
  226. {
  227.     boolean tried_vault = FALSE;
  228.  
  229.     /* make rooms until satisfied */
  230.     /* rnd_rect() will returns 0 if no more rects are available... */
  231.     while(nroom < MAXNROFROOMS && rnd_rect()) {
  232.         if(nroom >= (MAXNROFROOMS/6) && rn2(2) && !tried_vault) {
  233.             tried_vault = TRUE;
  234.             if (create_vault()) {
  235.                 vault_x = rooms[nroom].lx;
  236.                 vault_y = rooms[nroom].ly;
  237.                 rooms[nroom].hx = -1;
  238.             }
  239.         } else
  240.             if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
  241.             return;
  242.     }
  243.     return;
  244. }
  245.  
  246. static void
  247. join(a,b,nxcor)
  248. register int a, b;
  249. boolean nxcor;
  250. {
  251.     coord cc,tt, org, dest;
  252.     register int tx, ty, xx, yy;
  253.     register struct mkroom *croom, *troom;
  254.     register int dx, dy;
  255.  
  256.     croom = &rooms[a];
  257.     troom = &rooms[b];
  258.  
  259.     /* find positions cc and tt for doors in croom and troom
  260.        and direction for a corridor between them */
  261.  
  262.     if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
  263.     if(troom->lx > croom->hx) {
  264.         dx = 1;
  265.         dy = 0;
  266.         xx = croom->hx+1;
  267.         tx = troom->lx-1;
  268.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  269.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  270.     } else if(troom->hy < croom->ly) {
  271.         dy = -1;
  272.         dx = 0;
  273.         yy = croom->ly-1;
  274.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  275.         ty = troom->hy+1;
  276.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  277.     } else if(troom->hx < croom->lx) {
  278.         dx = -1;
  279.         dy = 0;
  280.         xx = croom->lx-1;
  281.         tx = troom->hx+1;
  282.         finddpos(&cc, xx, croom->ly, xx, croom->hy);
  283.         finddpos(&tt, tx, troom->ly, tx, troom->hy);
  284.     } else {
  285.         dy = 1;
  286.         dx = 0;
  287.         yy = croom->hy+1;
  288.         ty = troom->ly-1;
  289.         finddpos(&cc, croom->lx, yy, croom->hx, yy);
  290.         finddpos(&tt, troom->lx, ty, troom->hx, ty);
  291.     }
  292.     xx = cc.x;
  293.     yy = cc.y;
  294.     tx = tt.x - dx;
  295.     ty = tt.y - dy;
  296.     if(nxcor && levl[xx+dx][yy+dy].typ)
  297.         return;
  298.     if (okdoor(xx,yy) || !nxcor)
  299.         dodoor(xx,yy,croom);
  300.  
  301.     org.x  = xx+dx; org.y  = yy+dy;
  302.     dest.x = tx; dest.y = ty;
  303.  
  304.     if (!dig_corridor(org, dest, nxcor, CORR, STONE))
  305.         return;
  306.  
  307.     /* we succeeded in digging the corridor */
  308.     if (okdoor(tt.x, tt.y) || !nxcor)
  309.         dodoor(tt.x, tt.y, troom);
  310.  
  311.     if(smeq[a] < smeq[b])
  312.         smeq[b] = smeq[a];
  313.     else
  314.         smeq[a] = smeq[b];
  315. }
  316.  
  317. void
  318. makecorridors()
  319. {
  320.     int a, b, i;
  321.     boolean any = TRUE;
  322.  
  323.     for(a = 0; a < nroom-1; a++) {
  324.         join(a, a+1, FALSE);
  325.         if(!rn2(50)) break; /* allow some randomness */
  326.     }
  327.     for(a = 0; a < nroom-2; a++)
  328.         if(smeq[a] != smeq[a+2])
  329.         join(a, a+2, FALSE);
  330.     for(a = 0; any && a < nroom; a++) {
  331.         any = FALSE;
  332.         for(b = 0; b < nroom; b++)
  333.         if(smeq[a] != smeq[b]) {
  334.             join(a, b, FALSE);
  335.             any = TRUE;
  336.         }
  337.     }
  338.     if(nroom > 2)
  339.         for(i = rn2(nroom) + 4; i; i--) {
  340.         a = rn2(nroom);
  341.         b = rn2(nroom-2);
  342.         if(b >= a) b += 2;
  343.         join(a, b, TRUE);
  344.         }
  345. }
  346.  
  347. void
  348. add_door(x,y,aroom)
  349. register int x, y;
  350. register struct mkroom *aroom;
  351. {
  352.     register struct mkroom *broom;
  353.     register int tmp;
  354.  
  355.     aroom->doorct++;
  356.     broom = aroom+1;
  357.     if(broom->hx < 0)
  358.         tmp = doorindex;
  359.     else
  360.         for(tmp = doorindex; tmp > broom->fdoor; tmp--)
  361.             doors[tmp] = doors[tmp-1];
  362.     doorindex++;
  363.     doors[tmp].x = x;
  364.     doors[tmp].y = y;
  365.     for( ; broom->hx >= 0; broom++) broom->fdoor++;
  366. }
  367.  
  368. static void
  369. dosdoor(x,y,aroom,type)
  370. register xchar x, y;
  371. register struct mkroom *aroom;
  372. register int type;
  373. {
  374.     boolean shdoor = ((*in_rooms(x, y, SHOPBASE))? TRUE : FALSE);
  375.  
  376.     if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
  377.         type = DOOR;
  378.     levl[x][y].typ = type;
  379.     if(type == DOOR) {
  380.         if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
  381.         if(!rn2(5))
  382.             levl[x][y].doormask = D_ISOPEN;
  383.         else if(!rn2(6))
  384.             levl[x][y].doormask = D_LOCKED;
  385.         else
  386.             levl[x][y].doormask = D_CLOSED;
  387.  
  388.         if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
  389.             levl[x][y].doormask |= D_TRAPPED;
  390.         } else
  391. #ifdef STUPID
  392.         if (shdoor)
  393.             levl[x][y].doormask = D_ISOPEN;
  394.         else
  395.             levl[x][y].doormask = D_NODOOR;
  396. #else
  397.         levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
  398. #endif
  399.         if(levl[x][y].doormask & D_TRAPPED) {
  400.         struct monst *mtmp;
  401.  
  402.         if (level_difficulty() >= 9 && !rn2(5) &&
  403.            !((mons[PM_SMALL_MIMIC].geno & (G_GENOD | G_EXTINCT)) &&
  404.              (mons[PM_LARGE_MIMIC].geno & (G_GENOD | G_EXTINCT)) &&
  405.              (mons[PM_GIANT_MIMIC].geno & (G_GENOD | G_EXTINCT)))) {
  406.             /* make a mimic instead */
  407.             levl[x][y].doormask = D_NODOOR;
  408.             mtmp = makemon(mkclass(S_MIMIC,0), x, y);
  409.             if (mtmp)
  410.             set_mimic_sym(mtmp);
  411.         }
  412.         }
  413.         /* newsym(x,y); */
  414.     } else { /* SDOOR */
  415.         if(shdoor || !rn2(5))    levl[x][y].doormask = D_LOCKED;
  416.         else            levl[x][y].doormask = D_CLOSED;
  417.  
  418.         if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
  419.     }
  420.  
  421.     add_door(x,y,aroom);
  422. }
  423.  
  424. static boolean
  425. place_niche(aroom,dy,xx,yy)
  426. register struct mkroom *aroom;
  427. int *dy, *xx, *yy;
  428. {
  429.     coord dd;
  430.  
  431.     if(rn2(2)) {
  432.         *dy = 1;
  433.         finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
  434.     } else {
  435.         *dy = -1;
  436.         finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
  437.     }
  438.     *xx = dd.x;
  439.     *yy = dd.y;
  440.     return(isok(*xx,*yy+*dy) && levl[*xx][(*yy)+(*dy)].typ == STONE);
  441. }
  442.  
  443. /* there should be one of these per trap */
  444. const char *trap_engravings[TRAPNUM] = {
  445.                 "", "", "", "", "", "", "",
  446.                 "", "", "", "", "", "",
  447.                 "ad ae?ar um", "?la? ?as ?er?", "ad ae?ar um",
  448.                 "", "", "", ""
  449. #ifdef POLYSELF
  450.                 ,""
  451. #endif
  452.                 };
  453.  
  454. static void
  455. makeniche(trap_type)
  456. int trap_type;
  457. {
  458.     register struct mkroom *aroom;
  459.     register struct rm *rm;
  460.     register int vct = 8;
  461.     int dy, xx, yy;
  462.     register struct trap *ttmp;
  463.  
  464.     if(doorindex < DOORMAX)
  465.       while(vct--) {
  466.         aroom = &rooms[rn2(nroom)];
  467.         if(aroom->rtype != OROOM) continue;    /* not an ordinary room */
  468.         if(aroom->doorct == 1 && rn2(5)) continue;
  469.         if(!place_niche(aroom,&dy,&xx,&yy)) continue;
  470.  
  471.         rm = &levl[xx][yy+dy];
  472.         if(trap_type || !rn2(4)) {
  473.  
  474.         rm->typ = SCORR;
  475.         if(trap_type) {
  476.             if(trap_type == TRAPDOOR && !Can_fall_thru(&u.uz))
  477.             trap_type = ROCKTRAP;
  478.             ttmp = maketrap(xx, yy+dy, trap_type);
  479.             ttmp->once = 1;
  480.             if (*trap_engravings[trap_type])
  481.             make_engr_at(xx, yy-dy, trap_engravings[trap_type], 0L, DUST);
  482.         }
  483.         dosdoor(xx, yy, aroom, SDOOR);
  484.         } else {
  485.         rm->typ = CORR;
  486.         if(rn2(7))
  487.             dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
  488.         else {
  489.             (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy, TRUE);
  490.             if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE);
  491.         }
  492.         }
  493.         return;
  494.     }
  495. }
  496.  
  497. static void
  498. make_niches()
  499. {
  500.     register int ct = rnd((nroom>>1) + 1);
  501.     boolean    ltptr = TRUE,
  502.         vamp = TRUE;
  503.  
  504.     while(ct--) {
  505.  
  506.         if(depth(&u.uz) > 15 && !rn2(6) && ltptr) {
  507.             ltptr = FALSE;
  508.             makeniche(LEVEL_TELEP);
  509.         } else if(depth(&u.uz) > 5 && depth(&u.uz) < 25
  510.                             && !rn2(6) && vamp) {
  511.             vamp = FALSE;
  512.             makeniche(TRAPDOOR);
  513.         } else    makeniche(NO_TRAP);
  514.     }
  515. }
  516.  
  517. static void
  518. makevtele()
  519. {
  520.     makeniche(TELEP_TRAP);
  521. }
  522.  
  523. /* clear out various globals that keep information on the current level.
  524.  * some of this is only necessary for some types of levels (maze, normal,
  525.  * special) but it's easier to put it all in one place than make sure
  526.  * each type initializes what it needs to separately.
  527.  */
  528. static void
  529. clear_level_structures()
  530. {
  531.     static struct rm zerorm = { cmap_to_glyph(S_stone),
  532.                         0, 0, 0, 0, 0, 0, 0, 0 };
  533.     register int x,y;
  534.     register struct rm *lev;
  535.  
  536.     for(x=0; x<COLNO; x++) {
  537.         lev = &levl[x][0];
  538.         for(y=0; y<ROWNO; y++) {
  539.         *lev++ = zerorm;
  540. #ifdef MICROPORT_BUG
  541.         level.objects[x][y] = (struct obj *)0;
  542.         level.monsters[x][y] = (struct monst *)0;
  543. #endif
  544.         }
  545.     }
  546. #ifndef MICROPORT_BUG
  547.     (void) memset((genericptr_t)level.objects, 0, sizeof(level.objects));
  548.     (void) memset((genericptr_t)level.monsters, 0, sizeof(level.monsters));
  549. #endif
  550.     level.flags.nfountains = 0;
  551.     level.flags.nsinks = 0;
  552.     level.flags.has_shop = 0;
  553.     level.flags.has_vault = 0;
  554.     level.flags.has_zoo = 0;
  555.     level.flags.has_court = 0;
  556.     level.flags.has_morgue = 0;
  557.     level.flags.has_beehive = 0;
  558. #ifdef ARMY
  559.     level.flags.has_barracks = 0;
  560. #endif
  561.     level.flags.has_temple = 0;
  562.     level.flags.has_swamp = 0;
  563.     level.flags.noteleport = 0;
  564.     level.flags.hardfloor = 0;
  565.     level.flags.nommap = 0;
  566.     level.flags.hero_memory = 1;
  567.     level.flags.shortsighted = 0;
  568.     level.flags.is_maze_lev = 0;
  569.     level.flags.is_cavernous_lev = 0;
  570.  
  571.     nroom = 0;
  572.     rooms[0].hx = -1;
  573.     nsubroom = 0;
  574.     doorindex = 0;
  575.     init_rect();
  576.     init_vault();
  577.     xdnstair = ydnstair = xupstair = yupstair = 0;
  578.     sstairs.sx = sstairs.sy = 0;
  579.     xdnladder = ydnladder = xupladder = yupladder = 0;
  580.     made_branch = FALSE;
  581. }
  582.  
  583. static void
  584. makelevel()
  585. {
  586.     register struct mkroom *croom, *troom;
  587.     register int tryct;
  588.     register int x, y;
  589.     struct monst *tmonst;    /* always put a web with a spider */
  590.  
  591.     if(wiz1_level.dlevel == 0) init_dungeons();
  592.     oinit();    /* assign level dependent obj probabilities */
  593.     clear_level_structures();
  594.  
  595.     {
  596.         register s_level *slev = Is_special(&u.uz);
  597.  
  598.         /* check for special levels */
  599. #ifdef REINCARNATION
  600.         if (slev && !Is_rogue_level(&u.uz))
  601. #else
  602.         if (slev)
  603. #endif
  604.         {
  605.             makemaz(slev->proto);
  606.             return;
  607.         } else if (dungeons[u.uz.dnum].proto[0]) {
  608.             makemaz("");
  609.             return;
  610. #ifdef MULDGN
  611.         } else if (In_mines(&u.uz)) {
  612.             makemaz("minefill");
  613.             return;
  614.         } else if (In_quest(&u.uz)) {
  615.             char    fillname[9];
  616.             s_level    *loc_lev;
  617.  
  618.             Sprintf(fillname, "%c-locate", pl_character[0]);
  619.             loc_lev = find_level(fillname);
  620.  
  621.             Sprintf(fillname, "%c-fill", pl_character[0]);
  622.             Strcat(fillname,
  623.                (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
  624.             makemaz(fillname);
  625.             return;
  626. #endif
  627.         } else if(In_hell(&u.uz) ||
  628.           (rn2(5) && u.uz.dnum == medusa_level.dnum
  629.               && depth(&u.uz) > depth(&medusa_level))) {
  630.             makemaz("");
  631.             return;
  632.         }
  633.     }
  634.  
  635.     /* otherwise, fall through - it's a "regular" level. */
  636.  
  637. #ifdef REINCARNATION
  638.     if (Is_rogue_level(&u.uz)) {
  639.         makeroguerooms();
  640.         makerogueghost();
  641.     } else
  642. #endif
  643.         makerooms();
  644.     sort_rooms();
  645.  
  646.     /* construct stairs (up and down in different rooms if possible) */
  647.     croom = &rooms[rn2(nroom)];
  648.     if (!Is_botlevel(&u.uz))
  649.          mkstairs(somex(croom), somey(croom), 0, croom);    /* down */
  650.     if (nroom > 1) {
  651.         troom = croom;
  652.         croom = &rooms[rn2(nroom-1)];
  653.         if (croom == troom) croom++;
  654.     }
  655.  
  656.     if (u.uz.dlevel != 1) {
  657.         xchar sx, sy;
  658.         do {
  659.         sx = somex(croom);
  660.         sy = somey(croom);
  661.         } while(occupied(sx, sy));
  662.         mkstairs(sx, sy, 1, croom);    /* up */
  663.     }
  664.  
  665. #ifdef REINCARNATION
  666.     if (Is_rogue_level(&u.uz)) goto skip0;
  667. #endif
  668.     makecorridors();
  669.     make_niches();
  670.  
  671.     /* make a secret treasure vault, not connected to the rest */
  672.     if(do_vault()) {
  673.         xchar w,h;
  674. #ifdef DEBUG
  675.         debugpline("trying to make a vault...");
  676. #endif
  677.         w = 1;
  678.         h = 1;
  679.         if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
  680.             fill_vault:
  681.             add_room(vault_x, vault_y, vault_x+w,
  682.                  vault_y+h, TRUE, VAULT, FALSE);
  683.             level.flags.has_vault = 1;
  684.             fill_room(&rooms[nroom - 1], FALSE);
  685. #ifdef MULDGN
  686.             mk_knox_portal(vault_x+w, vault_y+h);
  687. #endif
  688.             if(!rn2(3)) makevtele();
  689.         } else if(rnd_rect() && create_vault()) {
  690.             vault_x = rooms[nroom].lx;
  691.             vault_y = rooms[nroom].ly;
  692.             if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
  693.                 goto fill_vault;
  694.             else
  695.                 rooms[nroom].hx = -1;
  696.         }
  697.     }
  698.  
  699. #ifdef WIZARD
  700.     if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
  701. #endif
  702.     if(depth(&u.uz) > 1 &&
  703.        depth(&u.uz) < depth(&medusa_level) &&
  704.        rn2(depth(&u.uz)) < 3) mkroom(SHOPBASE);
  705.     else if(depth(&u.uz) > 4 && !rn2(6)) mkroom(COURT);
  706.     else if(depth(&u.uz) > 6 && !rn2(7)) mkroom(ZOO);
  707.     else if(depth(&u.uz) > 8 && !rn2(5)) mkroom(TEMPLE);
  708.     else if(depth(&u.uz) > 9 && !rn2(5) &&
  709.        !(mons[PM_KILLER_BEE].geno & (G_GENOD | G_EXTINCT))) mkroom(BEEHIVE);
  710.     else if(depth(&u.uz) > 11 && !rn2(6)) mkroom(MORGUE);
  711.     else
  712. #ifdef ARMY
  713.     if(depth(&u.uz) > 14 && !rn2(4) &&
  714.        !(mons[PM_SOLDIER].geno & (G_GENOD | G_EXTINCT))) mkroom(BARRACKS);
  715.     else
  716. #endif
  717.     if(depth(&u.uz) > 18 && !rn2(6)) mkroom(SWAMP);
  718.  
  719. #ifdef REINCARNATION
  720. skip0:
  721. #endif
  722.     /* Place multi-dungeon branch. */
  723.     place_branch(Is_branchlev(&u.uz), 0, 0);
  724.  
  725.     /* for each room: put things inside */
  726.     for(croom = rooms; croom->hx > 0; croom++) {
  727.         if(croom->rtype != OROOM) continue;
  728.  
  729.         /* put a sleeping monster inside */
  730.         /* Note: monster may be on the stairs. This cannot be
  731.            avoided: maybe the player fell through a trap door
  732.            while a monster was on the stairs. Conclusion:
  733.            we have to check for monsters on the stairs anyway. */
  734.  
  735.         if(u.uhave.amulet || !rn2(3)) {
  736.             x = somex(croom); y = somey(croom);
  737.             tmonst = makemon((struct permonst *) 0, x,y);
  738.             if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] &&
  739.             !is_pool(x,y))
  740.             (void) maketrap (x,y,WEB);
  741.         }
  742.         /* put traps and mimics inside */
  743.         goldseen = FALSE;
  744.         x = 8 - (level_difficulty()/6);
  745.         if (x <= 1) x = 2;
  746.         while (!rn2(x))
  747.             mktrap(0,0,croom,(coord*)0);
  748.         if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
  749. #ifdef REINCARNATION
  750.         if(Is_rogue_level(&u.uz)) goto skip_nonrogue;
  751. #endif
  752.         if(!rn2(10)) mkfount(0,croom);
  753. #ifdef SINKS
  754.         if(!rn2(60)) mksink(croom);
  755. #endif
  756.         if(!rn2(60)) mkaltar(croom);
  757.         /* put statues inside */
  758.         if(!rn2(20))
  759.             (void) mkcorpstat(STATUE, (struct permonst *)0,
  760.                       somex(croom), somey(croom), TRUE);
  761.  
  762.         /* put box/chest inside;
  763.          *  40% chance for at least 1 box, regardless of number
  764.          *  of rooms; about 5 - 7.5% for 2 boxes, least likely
  765.          *  when few rooms; chance for 3 or more is neglible.
  766.          */
  767.         if(!rn2(nroom * 5 / 2))
  768.             (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
  769.                      somex(croom), somey(croom), TRUE);
  770.  
  771.         /* maybe make some graffiti */
  772.         if(!rn2(27 + 3 * depth(&u.uz))) {
  773.             const char *mesg = random_engraving();
  774.             if (mesg) {
  775.             do {
  776.                 x = somex(croom);  y = somey(croom);
  777.             } while(levl[x][y].typ != ROOM && !rn2(40));
  778.             if (!(IS_POOL(levl[x][y].typ) ||
  779.                   IS_FURNITURE(levl[x][y].typ)))
  780.                 make_engr_at(x, y, mesg, 0L, MARK);
  781.             }
  782.         }
  783.  
  784. #ifdef REINCARNATION
  785.     skip_nonrogue:
  786. #endif
  787.         if(!rn2(3)) {
  788.             (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
  789.             tryct = 0;
  790.             while(!rn2(5)) {
  791.             if(++tryct > 100) {
  792.                 impossible("tryct overflow4");
  793.                 break;
  794.             }
  795.             (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
  796.             }
  797.         }
  798.     }
  799. }
  800.  
  801. void
  802. mklev()
  803. {
  804.     struct mkroom *croom;
  805.  
  806.     if(getbones()) return;
  807.     in_mklev = TRUE;
  808.     makelevel();
  809.     bound_digging();
  810.     in_mklev = FALSE;
  811.     if(!level.flags.is_maze_lev) {
  812.         for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
  813. #ifdef SPECIALIZATION
  814.         topologize(croom, FALSE);
  815. #else
  816.         topologize(croom);
  817. #endif
  818.     }
  819. }
  820.  
  821. void
  822. #ifdef SPECIALIZATION
  823. topologize(croom, do_ordinary)
  824. register struct mkroom *croom;
  825. boolean do_ordinary;
  826. #else
  827. topologize(croom)
  828. register struct mkroom *croom;
  829. #endif
  830. {
  831.     register int x, y, roomno = (croom - rooms) + ROOMOFFSET;
  832.     register int lowx = croom->lx, lowy = croom->ly;
  833.     register int hix = croom->hx, hiy = croom->hy;
  834. #ifdef SPECIALIZATION
  835.     register schar rtype = croom->rtype;
  836. #endif
  837.     register int subindex, nsubrooms = croom->nsubrooms;
  838.  
  839.     /* skip the room if already done; i.e. a shop handled out of order */
  840.     /* also skip if this is non-rectangular (it _must_ be done already) */
  841.     if (levl[lowx][lowy].roomno == roomno || croom->irregular)
  842.         return;
  843. #ifdef SPECIALIZATION
  844. # ifdef REINCARNATION
  845.     if (Is_rogue_level(&u.uz))
  846.         do_ordinary = TRUE;        /* vision routine helper */
  847. # endif
  848.     if ((rtype != OROOM) || do_ordinary)
  849. #endif
  850.     {
  851.         /* do innards first */
  852.         for(x = lowx; x <= hix; x++)
  853.         for(y = lowy; y <= hiy; y++)
  854. #ifdef SPECIALIZATION
  855.             if (rtype == OROOM)
  856.             levl[x][y].roomno = NO_ROOM;
  857.             else
  858. #endif
  859.             levl[x][y].roomno = roomno;
  860.         /* top and bottom edges */
  861.         for(x = lowx-1; x <= hix+1; x++)
  862.         for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  863.             levl[x][y].edge = 1;
  864.             if (levl[x][y].roomno)
  865.             levl[x][y].roomno = SHARED;
  866.             else
  867.             levl[x][y].roomno = roomno;
  868.         }
  869.         /* sides */
  870.         for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  871.         for(y = lowy; y <= hiy; y++) {
  872.             levl[x][y].edge = 1;
  873.             if (levl[x][y].roomno)
  874.             levl[x][y].roomno = SHARED;
  875.             else
  876.             levl[x][y].roomno = roomno;
  877.         }
  878.     }
  879.     /* subrooms */
  880.     for (subindex = 0; subindex < nsubrooms; subindex++)
  881. #ifdef SPECIALIZATION
  882.         topologize(croom->sbrooms[subindex], (rtype != OROOM));
  883. #else
  884.         topologize(croom->sbrooms[subindex]);
  885. #endif
  886. }
  887.  
  888. /* Find an unused room for a branch location. */
  889. static struct mkroom *
  890. find_branch_room(mp)
  891.     coord *mp;
  892. {
  893.     struct mkroom *croom = 0;
  894.  
  895.     if (nroom == 0) {
  896.     mazexy(mp);        /* already verifies location */
  897.     } else {
  898.     /* not perfect - there may be only one stairway */
  899.     if(nroom > 2) {
  900.         int tryct = 0;
  901.  
  902.         do
  903.         croom = &rooms[rn2(nroom)];
  904.         while((croom == dnstairs_room || croom == upstairs_room ||
  905.           croom->rtype != OROOM) && (++tryct < 100));
  906.     } else
  907.         croom = &rooms[rn2(nroom)];
  908.  
  909.     do {
  910.         if (!somexy(croom, mp))
  911.         impossible("Can't place branch!");
  912.     } while(occupied(mp->x, mp->y) ||
  913.         (levl[mp->x][mp->y].typ != CORR && levl[mp->x][mp->y].typ != ROOM));
  914.     }
  915.     return croom;
  916. }
  917.  
  918. /* Find the room for (x,y).  Return NULL of not in a room. */
  919. static struct mkroom *
  920. pos_to_room(x, y)
  921.     xchar x, y;
  922. {
  923.     int i;
  924.     struct mkroom *curr;
  925.  
  926.     for (curr = rooms, i = 0; i < nroom; curr++, i++)
  927.     if (inside_room(curr, x, y)) return curr;;
  928.     return (struct mkroom *) 0;
  929. }
  930.  
  931.  
  932. /* If given a branch, randomly place a special stair or portal. */
  933. void
  934. place_branch(br, x, y)
  935. branch *br;    /* branch to place */
  936. xchar x, y;    /* location */
  937. {
  938.     coord          m;
  939.     d_level          *dest;
  940.     boolean          make_stairs;
  941.     struct mkroom *br_room;
  942.  
  943.     /*
  944.      * Return immediately if there is no branch to make or we have
  945.      * already made one.  This routine can be called twice when
  946.      * a special level is loaded that specifies an SSTAIR location
  947.      * as a favored spot for a branch.
  948.      */
  949.     if (!br || made_branch) return;
  950.  
  951.     if (!x) {    /* find random coordinates for branch */
  952.         br_room = find_branch_room(&m);
  953.         x = m.x;
  954.         y = m.y;
  955.     } else {
  956.         br_room = pos_to_room(x, y);
  957.     }
  958.  
  959.     if (on_level(&br->end1, &u.uz)) {
  960.         /* we're on end1 */
  961.         make_stairs = br->type != BR_NO_END1;
  962.         dest = &br->end2;
  963.     } else {
  964.         /* we're on end2 */
  965.         make_stairs = br->type != BR_NO_END2;
  966.         dest = &br->end1;
  967.     }
  968.  
  969.     if (br->type == BR_PORTAL) {
  970.         mkportal(x, y, dest->dnum, dest->dlevel);
  971.     } else if (make_stairs) {
  972.         sstairs.sx = x;
  973.         sstairs.sy = y;
  974.         sstairs.up = (char) on_level(&br->end1, &u.uz) ?
  975.                         br->end1_up : !br->end1_up;
  976.         assign_level(&sstairs.tolev, dest);
  977.         sstairs_room = br_room;
  978.  
  979.         levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
  980.         levl[x][y].typ = STAIRS;
  981.     }
  982.     /*
  983.      * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
  984.      * make_stairs is false) since there is currently only one branch
  985.      * per level, if we failed once, we're going to fail again on the
  986.      * next call.
  987.      */
  988.     made_branch = TRUE;
  989. }
  990.  
  991. static boolean
  992. bydoor(x, y)
  993. register xchar x, y;
  994. {
  995.     register boolean tmp1, tmp2;
  996.  
  997.     /* break up large expression to help some compilers */
  998.     tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
  999.         IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
  1000.     tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
  1001.         IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
  1002.     return(tmp1 || tmp2);
  1003. }
  1004.  
  1005. /* see whether it is allowable to create a door at [x,y] */
  1006. int
  1007. okdoor(x,y)
  1008. register xchar x, y;
  1009. {
  1010.     register boolean near_door = bydoor(x, y);
  1011.  
  1012.     return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
  1013.             doorindex < DOORMAX && !near_door);
  1014. }
  1015.  
  1016. void
  1017. dodoor(x,y,aroom)
  1018. register int x, y;
  1019. register struct mkroom *aroom;
  1020. {
  1021.     if(doorindex >= DOORMAX) {
  1022.         impossible("DOORMAX exceeded?");
  1023.         return;
  1024.     }
  1025.  
  1026.     dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
  1027. }
  1028.  
  1029. boolean
  1030. occupied(x, y)
  1031. register xchar x, y;
  1032. {
  1033.     return(t_at(x, y) || levl[x][y].typ == STAIRS
  1034.         || IS_FOUNTAIN(levl[x][y].typ)
  1035.         || IS_THRONE(levl[x][y].typ)
  1036. #ifdef SINKS
  1037.         || IS_SINK(levl[x][y].typ)
  1038. #endif
  1039.         || levl[x][y].typ == ALTAR
  1040.         || is_lava(x,y)
  1041.         || is_pool(x,y)
  1042.         || invocation_pos(x,y)
  1043.         );
  1044. }
  1045.  
  1046. /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
  1047. /* if tm != NULL, make trap at that location */
  1048. void
  1049. mktrap(num, mazeflag, croom, tm)
  1050. register int num, mazeflag;
  1051. register struct mkroom *croom;
  1052. coord *tm;
  1053. {
  1054.     register int kind;
  1055.     coord m;
  1056.  
  1057.     /* no traps in pools */
  1058.     if (tm && is_pool(tm->x,tm->y)) return;
  1059.  
  1060.     if (num > 0 && num < TRAPNUM) {
  1061.         kind = num;
  1062. #ifdef REINCARNATION
  1063.     } else if (Is_rogue_level(&u.uz)) {
  1064.         switch (rn2(7)) {
  1065.         default: kind = BEAR_TRAP; break; /* 0 */
  1066.         case 1: kind = ARROW_TRAP; break;
  1067.         case 2: kind = DART_TRAP; break;
  1068.         case 3: kind = TRAPDOOR; break;
  1069.         case 4: kind = PIT; break;
  1070.         case 5: kind = SLP_GAS_TRAP; break;
  1071.         case 6: kind = RUST_TRAP; break;
  1072.         }
  1073. #endif
  1074.     } else if (Inhell && !rn2(5)) {
  1075.         /* bias the frequency of fire traps in Gehennom */
  1076.         kind = FIRE_TRAP;
  1077.     } else {
  1078.         unsigned lvl = level_difficulty();
  1079.  
  1080.         do {
  1081.         kind = rnd(TRAPNUM-1);
  1082.         /* reject "too hard" traps */
  1083.         switch (kind) {
  1084.             case LEVEL_TELEP:
  1085.             case LANDMINE:
  1086.             if (lvl < 5) kind = NO_TRAP; break;
  1087.             case SPIKED_PIT:
  1088. #ifdef POLYSELF
  1089.             case POLY_TRAP:
  1090. #endif
  1091.             if (lvl < 6) kind = NO_TRAP; break;
  1092.             case WEB:
  1093.             case STATUE_TRAP:
  1094.             if (lvl < 7) kind = NO_TRAP; break;
  1095.             case FIRE_TRAP:
  1096.             if (!Inhell) kind = NO_TRAP; break;
  1097.         }
  1098.         } while (kind == NO_TRAP || kind == MAGIC_PORTAL);
  1099.     }
  1100.  
  1101.     if (kind == TRAPDOOR && !Can_fall_thru(&u.uz)) kind = ROCKTRAP;
  1102.  
  1103.     if (tm)
  1104.         m = *tm;
  1105.     else {
  1106.         register int tryct = 0;
  1107.  
  1108.         do {
  1109.         if (++tryct > 200)
  1110.             return;
  1111.         if (mazeflag)
  1112.             mazexy(&m);
  1113.         else if (!somexy(croom,&m))
  1114.             return;
  1115.         } while (occupied(m.x, m.y) || is_pool(m.x,m.y) ||
  1116.                      (sobj_at(BOULDER, m.x, m.y) &&
  1117.                       (kind == PIT || kind == SPIKED_PIT ||
  1118.                        kind == TRAPDOOR)));
  1119.     }
  1120.  
  1121.     (void) maketrap(m.x, m.y, kind);
  1122.     if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y);
  1123. }
  1124.  
  1125. void
  1126. mkstairs(x, y, up, croom)
  1127. xchar x, y;
  1128. char  up;
  1129. struct mkroom *croom;
  1130. {
  1131.     if (! (x || y)) {
  1132.         impossible("mkstairs:  bogus stair attempt at (%d,%d)", x, y);
  1133.         return;
  1134.     }
  1135.  
  1136.     /*
  1137.      * We can't make a regular stair off an end of the dungeon.  This
  1138.      * attempt can happen when a special level is placed at an end and
  1139.      * has an up or down stair specified in its description file.
  1140.      */
  1141.     if ((dunlev(&u.uz) == 1 && up) ||
  1142.             (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
  1143.         return;
  1144.  
  1145.     if(up) {
  1146.         xupstair = x;
  1147.         yupstair = y;
  1148.         upstairs_room = croom;
  1149.     } else {
  1150.         xdnstair = x;
  1151.         ydnstair = y;
  1152.         dnstairs_room = croom;
  1153.     }
  1154.  
  1155.     levl[x][y].typ = STAIRS;
  1156.     levl[x][y].ladder = up ? LA_UP : LA_DOWN;
  1157. }
  1158.  
  1159. static
  1160. void
  1161. mkfount(mazeflag,croom)
  1162. register int mazeflag;
  1163. register struct mkroom *croom;
  1164. {
  1165.     coord m;
  1166.     register int tryct = 0;
  1167.  
  1168.     do {
  1169.         if(++tryct > 200) return;
  1170.         if(mazeflag)
  1171.         mazexy(&m);
  1172.         else
  1173.         if (!somexy(croom, &m))
  1174.             return;
  1175.     } while(occupied(m.x, m.y) || bydoor(m.x, m.y));
  1176.  
  1177.     /* Put a fountain at m.x, m.y */
  1178.     levl[m.x][m.y].typ = FOUNTAIN;
  1179.     /* Is it a "blessed" fountain? (affects drinking from fountain) */
  1180.     if(!rn2(7)) levl[m.x][m.y].blessedftn = 1;
  1181.  
  1182.     level.flags.nfountains++;
  1183. }
  1184.  
  1185. #ifdef SINKS
  1186. static void
  1187. mksink(croom)
  1188. register struct mkroom *croom;
  1189. {
  1190.     coord m;
  1191.     register int tryct = 0;
  1192.  
  1193.     do {
  1194.         if(++tryct > 200) return;
  1195.         if (!somexy(croom, &m))
  1196.         return;
  1197.     } while(occupied(m.x, m.y) || bydoor(m.x, m.y));
  1198.  
  1199.     /* Put a sink at m.x, m.y */
  1200.     levl[m.x][m.y].typ = SINK;
  1201.  
  1202.     level.flags.nsinks++;
  1203. }
  1204. #endif /* SINKS /**/
  1205.  
  1206.  
  1207. static void
  1208. mkaltar(croom)
  1209. register struct mkroom *croom;
  1210. {
  1211.     coord m;
  1212.     register int tryct = 0;
  1213.     aligntyp al;
  1214.  
  1215.     if(croom->rtype != OROOM) return;
  1216.  
  1217.     do {
  1218.         if(++tryct > 200) return;
  1219.         if (!somexy(croom, &m))
  1220.         return;
  1221.     } while(occupied(m.x, m.y) || bydoor(m.x, m.y));
  1222.  
  1223.     /* Put an altar at m.x, m.y */
  1224.     levl[m.x][m.y].typ = ALTAR;
  1225.  
  1226.     /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
  1227.     al = rn2((int)A_LAWFUL+2) - 1;
  1228.     levl[m.x][m.y].altarmask = Align2amask( al );
  1229. }
  1230.  
  1231. /*
  1232.  * Major level transmutation: add a set of stairs (to the Sanctum) after
  1233.  * an earthquake that leaves behind a a new topology, centered at inv_pos.
  1234.  * Assumes there are no rooms within the invocation area and that inv_pos
  1235.  * is not too close to the edge of the map.  Also assume the hero can see.
  1236.  */
  1237. void
  1238. mkinvokearea()
  1239. {
  1240.     int dist;
  1241.     xchar xmin = inv_pos.x, xmax = inv_pos.x;
  1242.     xchar ymin = inv_pos.y, ymax = inv_pos.y;
  1243.     register xchar i;
  1244.  
  1245.     pline("The floor shakes violently under you!");
  1246.     pline("The walls around you begin to move and fall down!");
  1247.     display_nhwindow(WIN_MESSAGE, TRUE);
  1248.  
  1249.     for(dist = 1; dist < 7; dist++) {
  1250.     xmin--; xmax++;
  1251.  
  1252.     /* top and bottom */
  1253.     if(dist != 3) { /* the area is wider that it is high */
  1254.         ymin--; ymax++;
  1255.         for(i = xmin+1; i < xmax; i++) {
  1256.         mkinvpos(i, ymin, dist);
  1257.         mkinvpos(i, ymax, dist);
  1258.         }
  1259.     }
  1260.  
  1261.     /* left and right */
  1262.     for(i = ymin; i <= ymax; i++) {
  1263.         mkinvpos(xmin, i, dist);
  1264.         mkinvpos(xmax, i, dist);
  1265.     }
  1266.  
  1267.     flush_screen(1);    /* make sure the new glyphs shows up */
  1268.     delay_output();
  1269.     }
  1270.  
  1271.     You("are standing at the top of a stairwell leading down!");
  1272.     mkstairs(u.ux, u.uy, 0, (struct mkroom *)0); /* down */
  1273.     newsym(u.ux, u.uy);
  1274.     vision_full_recalc = 1;    /* everything changed */
  1275. }
  1276.  
  1277. /* Change level topology.  Messes with vision tables and ignores things like
  1278.  * boulders in the name of a nice effect.  Vision will get fixed up again
  1279.  * immediately after the effect is complete.
  1280.  */
  1281. static void
  1282. mkinvpos(x,y,dist)
  1283. xchar x,y;
  1284. int dist;
  1285. {
  1286.     struct trap *ttmp;
  1287.     register struct rm *lev = &levl[x][y];
  1288.  
  1289.     unblock_point(x,y);    /* make sure vision knows this location is open */
  1290.  
  1291.     /* fake out saved state */
  1292.     lev->seen = FALSE;
  1293.     lev->doormask = 0;
  1294.     if(dist < 6) lev->lit = TRUE;
  1295.     lev->waslit = TRUE;
  1296.     lev->horizontal = FALSE;
  1297.     viz_array[y][x] = (dist < 6 ) ?
  1298.     (IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
  1299.     COULD_SEE;
  1300.  
  1301.     switch(dist) {
  1302.     case 1: /* fire traps */
  1303.     lev->typ = ROOM;
  1304.     if (is_pool(x,y)) break;
  1305.     ttmp = maketrap(x, y, FIRE_TRAP);
  1306.     ttmp->tseen = TRUE;
  1307.     break;
  1308.     case 2: /* lit room locations */
  1309.     case 3:
  1310.     case 6:
  1311.     if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp);
  1312.     lev->typ = ROOM;
  1313.     break;
  1314.     case 4: /* pools (aka a wide moat) */
  1315.     case 5:
  1316.     if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp);
  1317.     lev->typ = MOAT;
  1318.     break;
  1319.     default:
  1320.     impossible("mkinvpos called with dist %d", dist);
  1321.     break;
  1322.     }
  1323.  
  1324.     /* display new value of position; could have a monster/object on it */
  1325.     newsym(x,y);
  1326. }
  1327.  
  1328. #ifdef MULDGN
  1329. /*
  1330.  * The portal to Ludios is special.  The entrance can only occur within a
  1331.  * vault in the main dungeon at a depth greater than 10.  The Ludios branch
  1332.  * structure reflects this by having a bogus "source" dungeon:  the value
  1333.  * of n_dgns (thus, Is_branchlev() will never find it).
  1334.  *
  1335.  * Ludios will remain isolated until the branch is corrected by this function.
  1336.  */
  1337. static void
  1338. mk_knox_portal(x, y)
  1339. xchar x, y;
  1340. {
  1341.     extern int n_dgns;        /* from dungeon.c */
  1342.     d_level *source;
  1343.     branch *br;
  1344.     xchar u_depth;
  1345.  
  1346.     br = dungeon_branch("Fort Ludios");
  1347.     if (on_level(&knox_level, &br->end1)) {
  1348.         source = &br->end2;
  1349.     } else {
  1350.         /* disallow Knox branch on a level with one branch already */
  1351.         if(Is_branchlev(&u.uz))
  1352.         return;
  1353.         source = &br->end1;
  1354.     }
  1355.  
  1356.     /* Already set or 2/3 chance of deferring until a later level. */
  1357.     if (source->dnum < n_dgns || (rn2(3)
  1358. #ifdef WIZARD
  1359.                       && !wizard
  1360. #endif
  1361.                       )) return;
  1362.  
  1363.     if (! (u.uz.dnum == oracle_level.dnum        /* in main dungeon */
  1364.         && !at_dgn_entrance("The Quest")    /* but not Quest's entry */
  1365.         && (u_depth = depth(&u.uz)) > 10    /* beneath 10 */
  1366.         && u_depth < depth(&medusa_level))) /* and above Medusa */
  1367.         return;
  1368.  
  1369.     /* Adjust source to be current level and re-insert branch. */
  1370.     *source = u.uz;
  1371.     insert_branch(br, TRUE);
  1372.  
  1373. # ifdef DEBUG
  1374.     pline("Made knox portal.");
  1375. # endif
  1376.     place_branch(br, x, y);
  1377. }
  1378. #endif
  1379.  
  1380. /*mklev.c*/
  1381.